#include "spi_config.h"
#include "driver/spi_master.h"
#include "mcu_io_config.h"
#include "driver/gpio.h"

#define SPI_HOST    SPI2_HOST
spi_device_handle_t spi;

static esp_err_t ESP_SPI_GPIO_init(void)
{
    gpio_config_t io_conf;
    esp_err_t ret;
    
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    io_conf.pull_up_en   = GPIO_PULLUP_DISABLE;
    io_conf.pin_bit_mask = (1 << RST_Pin) | (1 << DC_Pin) | (1 << SPI_CS_Pin);
    ret = gpio_config(&io_conf);
    if(ret != ESP_OK)
    {
        return ret;
    }

    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    io_conf.pull_up_en   = GPIO_PULLUP_DISABLE;
    io_conf.pin_bit_mask = (1 << BUSY_Pin);
    ret = gpio_config(&io_conf);
    if(ret != ESP_OK)
    {
        return ret;
    }

    return ESP_OK;
}

esp_err_t ESP_SPI_write(uint8_t* pbuffer,uint32_t BytesLen)
{
    esp_err_t ret;
    spi_transaction_t t = {0};

    if (BytesLen == 0)
    {
        return ESP_FAIL;         // no need to send anything
    } 

    t.length = BytesLen*8;              // Len is in bytes, transaction length is in bits.
    t.tx_buffer = pbuffer;              // Data
    ret = spi_device_polling_transmit(spi, &t);  //Transmit!
    assert(ret==ESP_OK);            //Should have had no issues.

    return ret;
}

esp_err_t ESP_SPI_driver_init(void)
{
    esp_err_t ret;
    spi_bus_config_t bus_conf = {
        .mosi_io_num = MOSI_Pin,
        .miso_io_num = -1, //MISO_Pin,
        .sclk_io_num = SPICLK_Pin,
        .quadhd_io_num = -1,
        .quadwp_io_num = -1,
        .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE,
    };

    spi_device_interface_config_t dev_conf = {
        .clock_speed_hz = SPI_MASTER_FREQ_10M,   // Clock out at 10 MHz,
        .mode = 0,                  // SPI mode 0
        .queue_size = 7,            // 传输队列大小，决定了等待传输数据的数量
        // .cs_ena_pretrans  = 0,      // 传输前CS信号的建立时间
        // .cs_ena_posttrans = 0,      // 传输时CS信号的保持时间
        // .spics_io_num = SPI_CS_Pin, // 设置GPIO复用为CS引脚
    };

    // 初始化CS DC RST BUSY 引脚
    ret=ESP_SPI_GPIO_init();
    ESP_ERROR_CHECK(ret);

    //Initialize the SPI bus
    ret=spi_bus_initialize(SPI2_HOST, &bus_conf, SPI_DMA_CH_AUTO);
    ESP_ERROR_CHECK(ret);

    //Attach to the SPI bus
    ret=spi_bus_add_device(SPI2_HOST, &dev_conf, &spi);
    ESP_ERROR_CHECK(ret);
    
    return ret;
}